package com.yixun.qfbao.controller;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSONObject;
import com.yixun.qfbao.api.service.CompanyService;
import com.yixun.qfbao.api.service.WeiXinService;
import com.yixun.qfbao.api.service.login.LoginFactory;
import com.yixun.qfbao.apidto.base.CommonReqDTO;
import com.yixun.qfbao.constant.WxConstant;
import com.yixun.qfbao.constants.ApiConstant;
import com.yixun.qfbao.model.Company;
import com.yixun.qfbao.model.dto.CompanyDto;
import com.yixun.qfbao.model.enums.DelFlagEnum;
import com.yixun.qfbao.request.BaseRequest;
import com.yixun.qfbao.request.wx.CodeRequest;
import com.yixun.qfbao.request.wx.OpenIdRequest;
import com.yixun.qfbao.response.CommonResponse;
import com.yixun.qfbao.util.StringUtil;
import com.yixun.qfbao.util.WeixinCommon;
import com.yixun.qfbao.util.wxmsg.AesException;
import com.yixun.qfbao.util.wxmsg.WXBizMsgCrypt;
import com.yixun.qfbao.utils.HttpApi;
import com.yixun.qfbao.utils.JSONUtil;
import com.yixun.qfbao.xf.model.enums.ResultEnum;

@Controller
@ResponseBody
@RequestMapping("/weixin")
public class WeiXinController {

    private static final Logger logger = LoggerFactory.getLogger(WeiXinController.class);

    @Autowired
    private WeiXinService weiXinService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    LoginController loginController;

    @PostMapping(value = "/getWxConfig", produces = "application/json")
    public String getWxConfig(HttpServletRequest request) {
        String domain = request.getHeader(ApiConstant.ORIGIN);
        String companyUuid= request.getHeader(ApiConstant.COMPANY_UUID);
        String systemId = request.getHeader(ApiConstant.LOGINTYPE);
        String subDomain = null;
        if(StringUtils.isBlank(companyUuid)){
            if (domain.indexOf(".") == -1) {
                subDomain = domain.split(":")[1].split("//")[1];
            } else {
                subDomain = domain.substring(domain.indexOf("//") + 2, domain.indexOf("."));
            }
        }
        try {
            return JSONUtil.toJSONStringWithDateFormat(weiXinService.getWxConfig(companyUuid,subDomain,systemId));
        } catch (Exception e) {
            logger.error("getWxConfig error: {}", e);
            return null;
        }
    }

    @RequestMapping("/getUserForOpenId")
    public String getUserForOpenId(@RequestParam("openid") String openid){
        try {
            return JSONUtil.toJSONStringWithDateFormat(weiXinService.getUserInfoFor(openid));
        }catch (Exception e){
            return null;
        }
    }

    //静默授权
    public String getSnsapiBase(HttpServletRequest request, HttpServletResponse response,@RequestParam("returnUrl") String returnUrl){
        //1.获取用户信息
        String domain = request.getHeader(ApiConstant.ORIGIN);
        String companyUuid= request.getHeader(ApiConstant.COMPANY_UUID);
        CompanyDto companyDto = new CompanyDto();
        companyDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
        if(StringUtils.isNotBlank(companyUuid)){
            companyDto.setCompanyUuid(companyUuid);
        }else if(StringUtils.isNotBlank(domain)){
            companyDto.setDomain(domain);
        }
        Company company = companyService.selectByDto(companyDto);
        try {
            String state = companyUuid + "|" + URLEncoder.encode(returnUrl,"UTF-8");
            String weixinUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + company.getAppId() + "&redirect_uri=" + URLEncoder.encode(request.getRequestURI() + "/weixin/getWeiXinAuth", "UTF-8") + "&response_type=code&scope=snsapi_userinfo&state=" + state + "&connect_redirect=1#wechat_redirect";
        }catch (Exception e){

        }

        return null;
    }


    //微信静默授权回调页面
    @RequestMapping("/getWeiXinAuth")
    public void getWeiXinAuth(HttpServletRequest request, HttpServletResponse response, String bus_uri, @RequestParam("code") String code, @RequestParam("state") String state){
        System.out.println("bus_uri ===>" + bus_uri);
        System.out.println("bus_uri ===>" + request.getParameter("bus_uri"));
        System.err.println("code ===>" + code);
        System.err.println("state ===>" + state);
        String[] params = state.split("\\|");

        //获取openId
        Map<String,String> map = weiXinService.getWeiXinToken(code,params[0],params[4]);

        try{
            String url ="http://" + params[1] + URLDecoder.decode(params[2],"utf-8") + "?companyUuid="+ params[0] +"&openId=";
            if(map != null && map.size() > 0 && StringUtils.isNotBlank(map.get("openId"))) {
                url += map.get("openId");
            }
            url += "#/"+params[3] ;
            if(StringUtils.isNotBlank(bus_uri)) {
                url += "?redirectUrl=" + bus_uri;
            }
            System.out.printf("url ========================================================> " + url);
            if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
                //告诉ajax我是重定向
                response.setHeader("REDIRECT", "REDIRECT");
                //告诉ajax我重定向的路径
                response.setHeader("CONTENTPATH", url);
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            }else{
                response.sendRedirect(url);
            }
        }catch (Exception e){
            //跳转友情错误页面
            logger.error("getWeiXinAuth error: {}", e);
        }
    }
    
    @RequestMapping("/getAddress")
    public String getAddress(@RequestParam("lat") String lat, @RequestParam("lng") String lng){
        String url = "https://apis.map.qq.com/ws/geocoder/v1/";
        String params = "location="+lat+","+lng+"&key=TH5BZ-TFQ3W-LZORS-RI7ZM-C2REE-3EBRD&get_poi=0";
        String result = HttpApi.sendGet(url,params,null);
        logger.info("本次获取地址结果result=====" + result);
        return result;
    }

    @RequestMapping("/getAddressByIp")
    public String getAddressByIp(){
        String url = "https://apis.map.qq.com/ws/location/v1/ip";
        String params = "key=TH5BZ-TFQ3W-LZORS-RI7ZM-C2REE-3EBRD&get_poi=0";
        return HttpApi.sendGet(url,params,null);
    }
    
    
    /**
     * 验证微信服务器
     * step:
     * @param companyUuid
     * @param request
     * @return
     */
    @GetMapping("/wxMsgCallBack")
    public String wxMsgCallBack(String timestamp, String nonce, String signature, String echostr){
    	if(!WeixinCommon.checkSignature(signature, WxConstant.TOKEN, timestamp, nonce)) {
    		logger.error("WeiXinServiceImpl->wxMsgCallBack->传入参数非法:token:{},timestamp:{},nonce:{},signature:{}", 
    				WxConstant.TOKEN, timestamp, nonce, signature);
    		return "";
    	}
    	return echostr;
    }
    
    /**
     * 微信消息回调方法
     * step:
     * @param appId 通过服务器配置为对应的appId
     * @param request
     * @return
     * 	暂时预定为其他消息过来仍然需要TOKEN信息，在此进行统一获取
     */
    @PostMapping("/wxMsgCallBack")
    public void wxMsgCallBack(String appId, String msg_signature, 
    		String timestamp, String nonce, HttpServletRequest request){
    	//传入的密文数据
    	String fromXML = WeixinCommon.streamToString(request);
    	logger.info("WeiXinController -> wxMsgCallBack -> fromXML:{}", fromXML);
    	logger.info("WeiXinController -> wxMsgCallBack -> appId:{}", appId);
    	weiXinService.wxMsgCallBack(appId, fromXML);
//    	String fromXML = "<xml><ToUserName><![CDATA[gh_e96b293fc147]]></ToUserName><FromUserName><![CDATA[odlaI5_0_swA1Rqa9b9KqMCuv4bE]]></FromUserName><CreateTime>1600858215</CreateTime><MsgType><![CDATA[event]]></MsgType><Event><![CDATA[unsubscribe]]></Event><EventKey><![CDATA[]]></EventKey></xml>";
//    	weiXinService.wxMsgCallBack("wxd3bf8709f7c40faf", fromXML);
//		try {
//			
//			//消息解密
//			WXBizMsgCrypt pc = new WXBizMsgCrypt(WxConstant.TOKEN, WxConstant.ENCODING_KEY, appId);
//			String msgContent = pc.decryptMsg(msg_signature, timestamp, nonce, fromXML);
//			weiXinService.wxMsgCallBack(appId, msgContent);
//		} catch (AesException e) {
//			logger.error(e.getMessage(), e);
//		}
    }
    
    
    /**
     * 刷新公众号的关注信息至绑定信息表
     * 留有单个调用的appId入口，避免调用失败而无法单个调用的问题
     * @return
     */
    @PostMapping("/refreshAttetionToBindInfo")
    public String refreshAttetionToBindInfo(@RequestParam String appId) {
    	return weiXinService.refreshAttetionToBindInfo(appId);
    }
    
    /**
     * 各个渠道刷新openId的总入口
     * @param reqDto
     * @return
     */
    @PostMapping("/refreshOpenId")
    public CommonResponse refreshOpenId(@RequestBody CommonReqDTO reqDto, HttpServletRequest request) {
    	String companyUuid = StringUtils.isNotBlank(reqDto.getCompanyUuid())? reqDto.getCompanyUuid(): request.getHeader(ApiConstant.COMPANY_UUID);
    	String loginType = StringUtils.isNotBlank(reqDto.getLoginType())? reqDto.getLoginType(): request.getHeader(ApiConstant.LOGINTYPE);
    	logger.info("WeiXinController -> refreshOpenId -> companyUuid:{}", companyUuid);
    	logger.info("WeiXinController -> refreshOpenId -> loginType:{}", loginType);
    	String resMsg = weiXinService.refreshOpenId(reqDto.getOpenId(), reqDto.getUserId(), loginType, companyUuid);
    	CommonResponse res = new CommonResponse();
    	res.setCode(ResultEnum.SUCCESS.getNo());
    	res.setMsg(resMsg);
    	return res;
    }
    
    /**
     * 分销小程序根据jscode 刷新openId
     * @param reqDto
     * @return
     */
    @PostMapping("/refreshOpenIdByJsCode")
    public CommonResponse refreshOpenIdByJsCode(@RequestBody BaseRequest<CodeRequest> reqDto) {
    	CommonResponse res = new CommonResponse();
    	
    	JSONObject wxBindInfoJson = loginController.getUserOpenIdInfo(reqDto.getData().getCode(), 
    			reqDto.getLoginType(), reqDto.getCompanyUuid());
    	
    	if(wxBindInfoJson == null) {
    		res.setCode(ResultEnum.FAIL.getNo());
    		res.setMsg("入参非法");
    	}
    	
		CompanyDto entity = new CompanyDto();;
		entity.setCompanyUuid(reqDto.getCompanyUuid());
		Company company = companyService.selectByDto(entity);
		res.setCode(ResultEnum.FAIL.getNo());
		if(company != null) {
			String wxopenId = LoginFactory.getLoginService(reqDto.getLoginType()).updateOpenIdInfo(wxBindInfoJson, 
					reqDto.getUserId(), reqDto.getCompanyUuid(), company.getEnableWeappMsg());
			if(StringUtils.isNotBlank(wxopenId)) {
				res.setCode(ResultEnum.SUCCESS.getNo());
				res.setMsg(wxopenId);
			}
		}
    	return res;
    }
    
}
